package java_util.coo_util;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

public class C_Bytes {

    /**
     * 从字节数组中删除前导0x00。
     */
    public static byte[] stripLeadingNullBytes(byte[] input) {
        byte[] result = Arrays.copyOf(input, input.length);
        while (result.length > 0 && result[0] == 0x00) {
            result = Arrays.copyOfRange(result, 1, result.length);
        }
        return result;
    }

    static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();

    /**
     * 将字节数组转换为等效的十六进制字符串。
     */
    public static String toHexString(byte[] data) {
        char[] chars = new char[data.length * 2];
        for (int i = 0; i < data.length; i++) {
            chars[i * 2] = HEX_DIGITS[(data[i] >> 4) & 0xf];
            chars[i * 2 + 1] = HEX_DIGITS[data[i] & 0xf];
        }
        return new String(chars).toLowerCase();
    }

    /**
     * 将十六进制字符串转换为其等效的字节数组。
     */
    public static byte[] toByteArray(String data) {
        if (data == null) {
            return new byte[]{};
        }

        if (data.length() == 0) {
            return new byte[]{};
        }

        while (data.length() < 2) {
            data = "0" + data;
        }

        if (data.substring(0, 2).toLowerCase().equals("0x")) {
            data = data.substring(2);
        }
        if (data.length() % 2 == 1) {
            data = "0" + data;
        }

        data = data.toUpperCase();

        byte[] bytes = new byte[data.length() / 2];
        String hexString = new String(HEX_DIGITS);
        for (int i = 0; i < bytes.length; i++) {
            int byteConv = hexString.indexOf(data.charAt(i * 2)) * 0x10;
            byteConv += hexString.indexOf(data.charAt(i * 2 + 1));
            bytes[i] = (byte) (byteConv & 0xFF);
        }

        return bytes;
    }

    /**
     * 反转字节数组的字节性。
     *
     * @param data Byte array to flip
     * @return Flipped array
     */
    public static byte[] flipEndian(byte[] data) {
        if (data == null) {
            return new byte[0];
        }
        byte[] newData = new byte[data.length];
        for (int i = 0; i < data.length; i++) {
            newData[data.length - i - 1] = data[i];
        }

        return newData;
    }

    /**
     * 填充一个字节数组的前导字节。
     *
     * @param data Data that needs padding
     * @param size The final desired size of the data.
     * @param pad  The byte value to use in padding the data.
     * @return A padded array.
     */
    public static byte[] leftPad(byte[] data, int size, byte pad) {
        if (size <= data.length) {
            return data;
        }

        byte[] newData = new byte[size];
        for (int i = 0; i < size; i++) {
            newData[i] = pad;
        }
        for (int i = 0; i < data.length; i++) {
            newData[size - i - 1] = data[data.length - i - 1];
        }

        return newData;
    }

    /**
     * 读取字节数组的一部分并将其作为自己的字节数组返回，与子字符串没有什么不同。
     *
     * @param data  Byte array to read from.
     * @param start Starting position of the desired data.
     * @param size  Size of the data.
     * @return Byte array containing the desired data.
     */
    public static byte[] S_SubBytes(byte[] data, int start, int size) {
        if (data.length < start + size) {
            return new byte[0];
        }

        byte[] newData = Arrays.copyOfRange(data, start, start + size);

        return newData;
    }

    /**
     * @param bytes
     * @param startPosi
     * @return
     */
    public static byte[] S_SubBytes(byte[] bytes, int startPosi) {
        byte[] bytes0 = new byte[bytes.length - startPosi];
        System.arraycopy(bytes, startPosi, bytes0, 0, bytes0.length);
        return bytes0;
    }


    /**
     * 添加
     *
     * @param bytes
     * @param bb
     * @return
     */
    public static byte[] S_Add(byte[] bytes, byte[] bb) {
        byte[] b3 = new byte[bytes.length + bb.length];
        System.arraycopy(bytes, 0, b3, 0, bytes.length);
        System.arraycopy(bb, 0, b3, bytes.length, bb.length);
        return b3;
    }

    /**
     * 截取
     *
     * @param bytes
     * @param startPosi
     * @param cutLength
     * @return
     */
    public static byte[] S_Cut(byte[] bytes, int startPosi, int cutLength) {
        byte[] bb = new byte[cutLength];
        System.arraycopy(bytes, startPosi, bb, 0, bb.length);
        return bb;
    }


    //10进制 到 256 进制
    public static byte[] S_10EncodeTo256Encode(int ii, int length) {
        byte[] zData = new byte[length];
        for (int i = 0; i < length; i++) {
            zData[i] = (byte) (ii >> 8 * i & 0xff);
            if (ii >> 8 * i < 256) {
                break;
            }
        }
        return zData;
    }

    //S_256进制 到 10进制
    public static int S_256EncodeTo10Encode(byte[] bytes) {
        int ii = 0;
        for (int i = 0; i < bytes.length; i++) {
            ii += (int) (bytes[i] << 8 * i);
        }
        return ii;
    }


    void S_mmm() {
//        int i = 123;
//        byte[] intBuff = BitConverter.GetBytes(i); // 将 int 转换成字节数组
//        // lob.Write(intBuff, 0, 4);
//        i = BitConverter.ToInt32(intBuff, 0); // 从字节数组转换成 int
//
//        double x = 123.456;
//        byte[] doubleBuff = BitConverter.GetBytes(x); // 将 double 转换成字节数组
//        // lob.Write(doubleBuff, 0, 8);
//        x = BitConverter.ToDouble(doubleBuff, 0); // 从字节数组转换成 double
    }

    /**
     * byte[]转int
     *
     * @param bs
     * @return
     */
    public static int bytes2Int(byte[] bs) {
        int retVal = 0;
        int len = bs.length < 4 ? bs.length : 4;
        for (int i = 0; i < len; i++) {
            retVal |= (bs[i] & 0xFF) << ((i & 0x03) << 3);
        }
        return retVal;

        // 如果确定足4位，可直接返回值
//        return (bs[0]&0xFF) | ((bs[1] & 0xFF)<<8) | ((bs[2] & 0xFF)<<16) | ((bs[3] & 0xFF)<<24);
    }

    /**
     * int转byte[]
     *
     * @param n
     * @return
     */
    public static byte[] int2Bytes(int n) {
        byte[] bs = new byte[4];
        bs[0] = (byte) n;
        bs[1] = (byte) (n >> 8);
        bs[2] = (byte) (n >> 16);
        bs[3] = (byte) (n >> 24);
        return bs;
    }

    /**
     * byte[]转int[]
     *
     * @param bs
     * @return
     */
    public static int[] bytes2Ints(byte[] bs) {
        int len = (bs.length & 0x03) == 0 ? (bs.length >> 2) : (bs.length >> 2) + 1;
        int[] is = new int[len];

        // 进行转换前必须保证is[]所有元素的值都是0，这里创建时默认都是0，所以不用初始化赋值
        for (int i = 0; i < bs.length; ++i) {
            is[i >> 2] |= (bs[i] & 0xFF) << ((i & 0x03) << 3);
        }
        return is;
    }

    /**
     * int[]转byte[]
     *
     * @param is
     * @return
     */
    public static byte[] ints2Bytes(int[] is) {
        byte[] bs = new byte[is.length << 2];
        int offset;
        for (int i = 0; i < is.length; i++) {
            offset = i << 2;
            bs[offset] = (byte) (is[i] & 0xFF);
            bs[offset + 1] = (byte) ((is[i] >> 8) & 0xFF);
            bs[offset + 2] = (byte) ((is[i] >> 16) & 0xFF);
            bs[offset + 3] = (byte) ((is[i] >> 24) & 0xFF);
        }
        return bs;
    }

    //字符串转换为byte[]
    public static byte[] S_StringToBytes(String sss) {
        byte[] bytes = new byte[0];
        try {
            // 可以指定编码，默认也只UTF-8
            bytes = sss.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return bytes;
    }
    //byte[]转换为字符串
    public static String S_BytesToString(byte[] bytes) {
        try {
            String str = new String(bytes, "UTF-8");
            return str;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }
}
